/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.servicecomb.fence.service.impl;

import java.sql.PreparedStatement;

import javax.annotation.Resource;

import org.apache.seata.core.context.RootContext;
import org.apache.servicecomb.fence.service.AccountService;
import org.apache.servicecomb.fence.service.OrderService;
import org.apache.servicecomb.provider.pojo.RpcReference;
import org.apache.servicecomb.provider.rest.common.RestSchema;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.stereotype.Component;

@RestSchema(schemaInterface = OrderService.class, schemaId = "OrderService")
@Component
public class OrderServiceImpl implements OrderService {

  private static final Logger LOGGER = LoggerFactory.getLogger(OrderService.class);

  @Resource
  private JdbcTemplate jdbcTemplate;

  @RpcReference(schemaId = "AccountService", microserviceName = "authentication-server")
  private AccountService accountService;

  @Override
  public void create(String userId, String commodityCode, int orderCount) {
    LOGGER.info("Order Service Begin ... xid: " + RootContext.getXID());

    // 计算订单金额
    int orderMoney = calculate(commodityCode, orderCount);

    // 从账户余额扣款
    accountService.debit(userId, orderMoney);

    LOGGER.info(
        "Order Service SQL: insert into order_tbl (user_id, commodity_code, count, money) values ({}, {}, {}, {})",
        userId, commodityCode, orderCount, orderMoney);

    KeyHolder keyHolder = new GeneratedKeyHolder();
    jdbcTemplate.update(con -> {
      PreparedStatement pst = con.prepareStatement(
          "insert into order_tbl (user_id, commodity_code, count, money) values (?, ?, ?, ?)",
          PreparedStatement.RETURN_GENERATED_KEYS);
      pst.setObject(1, userId);
      pst.setObject(2, commodityCode);
      pst.setObject(3, orderCount);
      pst.setObject(4, orderMoney);
      return pst;
    }, keyHolder);

    keyHolder.getKeys().forEach((k, v) -> LOGGER.info("Order Service End ... Created " + k + ":"
        + v));
  }

  private int calculate(String commodityId, int orderCount) {
    return 200 * orderCount;
  }
}